package com.thilux.servicemanager;

import java.util.Set;

import com.thilux.servicemanager.config.LoadType;
import com.thilux.servicemanager.config.Loader;
import com.thilux.servicemanager.exception.ServiceAlreadyRegisteredException;
import com.thilux.servicemanager.exception.ServiceNotFoundException;
import com.thilux.servicemanager.manager.Service;
import com.thilux.servicemanager.manager.ServiceInfo;

/**
 * Service locator for handling ServiceManager's mapped services.
 * @author tsantana
 *
 */
public class ServiceLocator {

    private static boolean isConfigLoaded = false;
    /**
     * Looks for a service, provided its name, into ServiceManager.
     * @param serviceName
     * @return
     * @throws ServiceNotFoundException
     */
    public static Service findService(String serviceName) throws ServiceNotFoundException{
	
	if(!isConfigLoaded){
	    try {
		new Loader();
		isConfigLoaded=true;
	    } catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		return null;
	    }
	}
	
	ServiceInfo serviceInfo = ServiceManager.mappedServices.get(serviceName);
	Service service = null;
	
	if(serviceInfo.getLoadType()==LoadType.LAZY){
	    try {
		service = (Service) serviceInfo.getServiceClass().newInstance();
	    } catch (InstantiationException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    } catch (IllegalAccessException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    }
	}else{
	    service = serviceInfo.getService();
	}
	
	if (service != null){
	    return service;
	}else{
	    throw new ServiceNotFoundException(serviceName);
	}
	
    }
    
    /**
     * Adds a new service to ServiceManager at runtime.
     * @param serviceName
     * @param service
     * @throws ServiceAlreadyRegisteredException
     */
    public static void registerService(String serviceName, Class serviceClass, boolean eager)
    	throws ServiceAlreadyRegisteredException{
	
	ServiceInfo serviceInfo = new ServiceInfo();
	
	serviceInfo.setServiceClass(serviceClass);
	if(eager){
	    serviceInfo.setLoadType(LoadType.EAGER);
	    try{
		serviceInfo.setService((Service) serviceClass.newInstance());
	    }catch(Exception e){
		e.printStackTrace();
	    }
	}else{
	    serviceInfo.setLoadType(LoadType.LAZY);
	    serviceInfo.setService(null);
	}
	
	
	if (ServiceManager.mappedServices.get(serviceName)==null){
	    
	    ServiceManager.mappedServices.put(serviceName, serviceInfo);
	    
	}else{
	    
	    throw new ServiceAlreadyRegisteredException("Service name already registered");
	}
	
	
    }
    
    public static Set<String> getServiceNames(){
	
	Set<String> serviceNames = ServiceManager.mappedServices.keySet();
	
	return serviceNames;
    }
    
}
